package com.mdd.front.service.staff.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mdd.common.constant.GlobalConstant;
import com.mdd.common.core.PageResult;
import com.mdd.common.dto.StaffDto;
import com.mdd.common.dto.result.StaffResultDto;
import com.mdd.common.entity.goods.Goods;
import com.mdd.common.entity.staff.Staff;
import com.mdd.common.enums.RecommendEnum;
import com.mdd.common.mapper.staff.StaffMapper;
import com.mdd.common.mapper.unit.GoodsUnitMapper;
import com.mdd.common.utils.ArrayUtil;
import com.mdd.common.utils.TimeUtil;
import com.mdd.common.utils.UrlUtil;
import com.mdd.front.service.IUserService;
import com.mdd.front.service.goods.IGoodsService;
import com.mdd.front.service.region.IDevRegionService;
import com.mdd.front.service.staff.IStaffService;
import com.mdd.front.vo.goods.GoodsDetailInfoVo;
import com.mdd.front.vo.staff.StaffDetailVo;
import com.mdd.front.vo.staff.StaffListVo;
import com.mdd.front.vo.staff.StaffPageParam;
import com.mdd.front.vo.user.UserInfoVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 师傅实现类
 */
@Service
public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements IStaffService {

    @Resource
    StaffMapper staffMapper;

    @Resource
    private IDevRegionService regionService;

    @Resource
    private IUserService userService;

    @Resource
    private IGoodsService goodsService;

    @Resource
    private GoodsUnitMapper unitMapper;

    /**
     * 师傅列表
     *
     * @param params 搜索参数
     * @return PageResult<StaffListVo>
     */
    @Override
    public PageResult<StaffListVo> list(StaffPageParam params) {
        Page<StaffListVo> page = new Page<>(params.getPageNo(), params.getPageSize());
        StaffDto pageDto = new StaffDto();
        BeanUtils.copyProperties(params, pageDto);
        pageDto.setStatus(1);
        Page<StaffResultDto> resultDtoPage = staffMapper.page(page, pageDto);
        if (resultDtoPage == null || CollectionUtils.isEmpty(resultDtoPage.getRecords())) {
            return PageResult.iPageHandle(0L, page.getCurrent(), page.getSize(), Lists.newArrayList());
        }
        Map<Long, String> goodsMap = this.getGoodsName(resultDtoPage);

        List<StaffListVo> list = new LinkedList<>();
        Map<Long, String> regionMap = regionService.getRegionMap();
        for (StaffResultDto item : resultDtoPage.getRecords()) {
            StaffListVo vo = new StaffListVo();
            BeanUtils.copyProperties(item, vo);
            vo.setProvince(regionMap.get(vo.getProvinceId()));
            vo.setCity(regionMap.get(vo.getCityId()));
            vo.setDistrict(regionMap.get(vo.getDistrictId()));
            vo.setAvatarUrl(UrlUtil.toAbsoluteUrl(item.getAvatarUri()));
            vo.setCreateTime(TimeUtil.timestampToDate(item.getCreateTime()));
            vo.setUpdateTime(TimeUtil.timestampToDate(item.getUpdateTime()));
            if (StringUtils.isNotEmpty(item.getGoodsIds())) {
                String[] split = StringUtils.split(item.getGoodsIds(), ",");
                StringBuilder sb = new StringBuilder();
                for (String goodId : split) {
                    sb.append(goodsMap.get(Long.valueOf(goodId))).append("、");
                }
                String goodsName = sb.toString();
                vo.setGoodsList(goodsName.substring(0, goodsName.length() - 1));
            }
            list.add(vo);
        }
        return PageResult.iPageHandle(resultDtoPage.getTotal(), resultDtoPage.getCurrent(), resultDtoPage.getSize(), list);
    }

    private Map<Long, String> getGoodsName(Page<StaffResultDto> resultDtoPage) {
        Set<Long> goodsIds = Sets.newHashSet();
        for (StaffResultDto record : resultDtoPage.getRecords()) {
            if (StringUtils.isEmpty(record.getGoodsIds())) {
                continue;
            }
            String[] split = StringUtils.split(record.getGoodsIds(), ",");
            for (String goodId : split) {
                goodsIds.add(Long.valueOf(goodId));
            }
        }
        List<Goods> goodsList = goodsService.listByIds(Lists.newArrayList(goodsIds));
        Map<Long, String> map = Maps.newHashMap();
        if (CollectionUtils.isEmpty(goodsList)) {
            return map;
        }
        return goodsList.stream().collect(Collectors.toMap(item -> item.getId(), item -> item.getName()));
    }

    /**
     * 师傅详情
     *
     * @param id 主键参数
     * @return Staff
     */
    @Override
    public StaffDetailVo detail(Long id) {
        Staff model = staffMapper.selectOne(
                new QueryWrapper<Staff>()
                        .eq("id", id)
                        .last("limit 1"));

        Assert.notNull(model, "数据不存在");
        StaffDetailVo vo = new StaffDetailVo();
        BeanUtils.copyProperties(model, vo);
        Map<Long, String> regionMap = regionService.getRegionMap();
        vo.setProvince(regionMap.get(vo.getProvinceId()));
        vo.setCity(regionMap.get(vo.getCityId()));
        vo.setDistrict(regionMap.get(vo.getDistrictId()));
        vo.setIsRecommendName(RecommendEnum.getMap().get(vo.getIsRecommend()));
        vo.setUserVo(userService.info(model.getUserId().intValue()));
        vo.setCreateTime(TimeUtil.timestampToDate(model.getCreateTime()));
        vo.setUpdateTime(TimeUtil.timestampToDate(model.getUpdateTime()));
        List<Long> goodsIds = Lists.newArrayList();
        List<String> goodsIdsStr = Arrays.asList(StringUtils.split(model.getGoodsIds(), ","));
        CollectionUtils.collect(goodsIdsStr, input -> Long.valueOf(input.toString()), goodsIds);
        List<Goods> goodsList = goodsService.listByIds(goodsIds);
        //过滤掉被删除的服务
        goodsList = goodsList.stream().filter(item -> item.getIsDelete() == 0).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(goodsList)) {
            List<Long> unitIds = goodsList.stream().filter(item -> item.getIsDelete() == 0).map(Goods::getUnitId).distinct().collect(Collectors.toList());
            Map<Long, String> unitMap = unitMapper.selectBatchIds(unitIds).stream().collect(Collectors.toMap(item -> item.getId(), item -> item.getName()));
            List<GoodsDetailInfoVo> goodsDetailVoList = Lists.newArrayList();
            for (Goods goods : goodsList) {
                GoodsDetailInfoVo goodsVo = new GoodsDetailInfoVo();
                BeanUtils.copyProperties(goods, goodsVo);
                goodsVo.setUnit(unitMap.get(goods.getUnitId()));
                goodsVo.setImage(UrlUtil.toAbsoluteUrl(goods.getImage()));
                goodsDetailVoList.add(goodsVo);
            }
            vo.setGoodsList(goodsDetailVoList);
        }
        return vo;
    }

    @Override
    public List<StaffDetailVo> listByCityId(Long cityId) {
        LambdaQueryWrapper<Staff> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(cityId != null && cityId > 0, Staff::getCityId, cityId);
        lambdaQueryWrapper.eq(Staff::getStatus, 1);
        lambdaQueryWrapper.eq(Staff::getIsDelete, GlobalConstant.NOT_DELETE);
        lambdaQueryWrapper.orderByDesc(Staff::getCreateTime);
        lambdaQueryWrapper.last("limit 10");
        List<Staff> list = super.list(lambdaQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        List<Long> userIds = list.stream().map(Staff::getUserId).collect(Collectors.toList());
        Map<Long, UserInfoVo> userMap = userService.listByIds(userIds).stream().collect(Collectors.toMap(item -> Long.valueOf(item.getId()), item -> item, (a, b) -> b));
        Set<Long> goodsSet = new HashSet<>();
        List<String> goodsIds = list.stream().map(Staff::getGoodsIds).collect(Collectors.toList());
        for (String goodsId : goodsIds) {
            String[] goodsIdsStr = StringUtils.split(goodsId, ",");
            for (String s : goodsIdsStr) {
                goodsSet.add(Long.valueOf(s));
            }
        }
        List<Goods> goodsList = goodsService.listByIds(Lists.newArrayList(goodsSet));
        Map<Long, Goods> goodsMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(goodsList)) {
            goodsMap = goodsList.stream().collect(Collectors.toMap(Goods::getId, item -> item));
        }
        List<StaffDetailVo> targetList = Lists.newArrayList();
        for (Staff staff : list) {
            StaffDetailVo vo = new StaffDetailVo();
            BeanUtils.copyProperties(staff, vo);
            vo.setUserVo(userMap.get(staff.getUserId()));
            String[] goodsIdsStr = StringUtils.split(staff.getGoodsIds(), ",");
            List<GoodsDetailInfoVo> targetGoodsList = Lists.newArrayList();
            for (String s : goodsIdsStr) {
                Goods goods = goodsMap.get(Long.valueOf(s));
                if (goods != null) {
                    GoodsDetailInfoVo goodsDetailVo = new GoodsDetailInfoVo();
                    BeanUtils.copyProperties(goods, goodsDetailVo);
                    targetGoodsList.add(goodsDetailVo);
                }
            }
            vo.setCreateTime(TimeUtil.timestampToDate(staff.getCreateTime()));
            vo.setUpdateTime(TimeUtil.timestampToDate(staff.getUpdateTime()));
            vo.setGoodsList(targetGoodsList);
            vo.setGoodsIds(ArrayUtil.stringToListAsStr(staff.getGoodsIds(),","));
            targetList.add(vo);
        }
        return targetList;
    }

    @Override
    public List<Staff> listStaff(Long goodsId, Long cityId) {
        LambdaQueryWrapper<Staff> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Staff::getCityId, cityId);
        lambdaQueryWrapper.like(Staff::getGoodsIds, goodsId);
        List<Staff> list = super.list(lambdaQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        Iterator<Staff> iterator = list.iterator();
        while (iterator.hasNext()) {
            Staff next = iterator.next();
            List<String> goodsIdStr = Arrays.asList(StringUtils.split(next.getGoodsIds(), ","));
            if (!goodsIdStr.contains(String.valueOf(goodsId))) {
                iterator.remove();
            }
        }
        return list;
    }

    @Override
    public Staff getById(Long staffId) {
        return super.getById(staffId);
    }

    @Override
    public Staff getByUserId(Long userId) {
        LambdaQueryWrapper<Staff> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Staff::getUserId, userId);
        lambdaQueryWrapper.eq(Staff::getIsDelete, GlobalConstant.NOT_DELETE);
        lambdaQueryWrapper.last("limit 1");
        return super.getOne(lambdaQueryWrapper);
    }

    @Override
    public List<Staff> getByCityId(Long cityId) {
        LambdaQueryWrapper<Staff> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Staff::getCityId, cityId);
        lambdaQueryWrapper.eq(Staff::getStatus, 1);
        lambdaQueryWrapper.eq(Staff::getIsDelete, GlobalConstant.NOT_DELETE);
        lambdaQueryWrapper.orderByDesc(Staff::getCreateTime);
        return super.list(lambdaQueryWrapper);
    }

}
